package com.wh.db.jdbc.mysql;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import com.wh.db.Page;
import com.wh.db.sql.SQLUtils;
import com.wh.lang.LogicException;
import com.wh.minihelp.filter.IFunctionContext;
import com.wh.web.util.log.Logs;

/**
 * 基础的Spring数据库操作封装
 * 
 * @author washheart@163.com
 * 
 */
public abstract class BaseJDBCDao {
	protected BaseJDBCOperations ds;
	protected IFunctionContext ctx;

	public BaseJDBCDao() {}

	public void setDataStore(BaseJDBCOperations ds) {
		this.ds = ds;
	}

	public boolean execute(String sql) {
		try {
			return ds.execute(sql);
		} catch (Throwable e) {
			throw new LogicException("执行" + sql + "出错", e);
		}
	}

	public <T> Page<T> getPage(final String querySql, final int start, final int count, IJDBCRowMapper<T> mapper) {
		// 构造Count查询语句
		final String countSql = " select count(*) " + SQLUtils.removeSelect(SQLUtils.removeOrders(querySql));
		return getPage(countSql, querySql, start, count, mapper);
	}

	public <T> Page<T> getPage(final String countSql, final String querySql, int start, final int count, IJDBCRowMapper<T> mapper) {
		if (start <= 0) start = 1;
		if (count < 0 || countSql == null || querySql == null) {
			throw new LogicException("参数不合法!");
		}
		Logs.println("countSql = " + countSql);
		Logs.println("querySql = " + querySql);
		try {
			Number number = ds.queryForObject(countSql);
			int total = (number != null ? number.intValue() : 0);
			if (total == 0) return Page.EMPTY_PAGE;
			int startRow = start;
			if (total <= count) {
				startRow = 1;
			} else if (start > total) {
				startRow = total - total % count;
				if (startRow == total) {
					startRow = total - count + 1;
				} else {
					startRow = startRow + 1;
				}
			}
			boolean hasNext = (startRow - 1 + count) < total;
			String strQuery = querySql//
					+ " limit " + count//
					+ " offset " + (start - 1);
			List<T> a = query(strQuery, mapper);
			return new Page<T>(a, startRow, count, total, hasNext);
		} catch (LogicException e) {
			throw e;
		} catch (Throwable e) {
			throw new LogicException("读写数据库错误", e);
		}
	}

	public <T> List<T> query(String strQuery, IJDBCRowMapper<T> mapper) {
		try {
			return ds.query(strQuery, mapper);
		} catch (Throwable e) {
			throw new LogicException("读写数据库错误", e);
		}
	}

	public void saveOrUpdateAll() throws SQLException {
		ds.saveOrUpdateAll();
	}

	public <T> void save(String sql, IJDBCRowSetter<T> setter, List<T> msgs) {
		try {
			ds.batchUpdate(sql, setter, msgs, msgs.size());
		} catch (Throwable e) {
			throw new LogicException("执行" + sql + "出错", e);
		}
	}

	public void initBy(IFunctionContext ctx) {
		this.ctx = ctx;
		Connection cnn = ctx.getConnection();
		BaseJDBCOperations ds = new BaseJDBCOperations();
		ds.initByConnection(cnn);
		this.setDataStore(ds);
	}
}
